<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<meta name="theme-color" content="#222"><meta name="generator" content="Hexo 6.3.0">

  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">



<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" integrity="sha256-CTSx/A06dm1B063156EVh15m6Y67pAjZZaQc89LLSrU=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.1.1/animate.min.css" integrity="sha256-PR7ttpcvz8qrF57fur/yAx1qXMFJeJFiA6pSzWi0OIE=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fancyapps-ui/5.0.24/fancybox/fancybox.css" integrity="sha256-vQkngPS8jiHHH0I6ABTZroZk8NPZ7b+MUReOFE9UsXQ=" crossorigin="anonymous">

<script class="next-config" data-name="main" type="application/json">{"hostname":"rjyblog.gitee.io","root":"/","images":"/images","scheme":"Pisces","darkmode":false,"version":"8.18.2","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12},"copycode":{"enable":true,"style":null},"fold":{"enable":false,"height":500},"bookmark":{"enable":false,"color":"#222","save":"auto"},"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"stickytabs":false,"motion":{"enable":true,"async":false,"transition":{"menu_item":"fadeInDown","post_block":"fadeIn","post_header":"fadeInDown","post_body":"fadeInDown","coll_header":"fadeInLeft","sidebar":"fadeInUp"}},"prism":false,"i18n":{"placeholder":"搜索...","empty":"没有找到任何搜索结果：${query}","hits_time":"找到 ${hits} 个搜索结果（用时 ${time} 毫秒）","hits":"找到 ${hits} 个搜索结果"},"path":"/search.xml","localsearch":{"enable":true,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false}}</script><script src="/js/config.js"></script>

    <meta name="description" content="ARouter源码分析">
<meta property="og:type" content="article">
<meta property="og:title" content="ARouter源码分析">
<meta property="og:url" content="https://rjyblog.gitee.io/posts/23659d3d.html">
<meta property="og:site_name" content="任建勇的博客">
<meta property="og:description" content="ARouter源码分析">
<meta property="og:locale" content="zh_CN">
<meta property="article:published_time" content="2023-09-14T09:23:33.000Z">
<meta property="article:modified_time" content="2023-10-18T01:34:04.463Z">
<meta property="article:author" content="Jason">
<meta property="article:tag" content="Android">
<meta property="article:tag" content="ARouter">
<meta name="twitter:card" content="summary">


<link rel="canonical" href="https://rjyblog.gitee.io/posts/23659d3d.html">



<script class="next-config" data-name="page" type="application/json">{"sidebar":"","isHome":false,"isPost":true,"lang":"zh-CN","comments":true,"permalink":"https://rjyblog.gitee.io/posts/23659d3d.html","path":"posts/23659d3d.html","title":"ARouter源码分析"}</script>

<script class="next-config" data-name="calendar" type="application/json">""</script>
<title>ARouter源码分析 | 任建勇的博客</title>
  








  <noscript>
    <link rel="stylesheet" href="/css/noscript.css">
  </noscript>
</head>

<body itemscope itemtype="http://schema.org/WebPage" class="use-motion">
  <div class="headband"></div>

  <main class="main">
    <div class="column">
      <header class="header" itemscope itemtype="http://schema.org/WPHeader"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏" role="button">
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <i class="logo-line"></i>
      <p class="site-title">任建勇的博客</p>
      <i class="logo-line"></i>
    </a>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger" aria-label="搜索" role="button">
        <i class="fa fa-search fa-fw fa-lg"></i>
    </div>
  </div>
</div>



<nav class="site-nav">
  <ul class="main-menu menu"><li class="menu-item menu-item-home"><a href="/" rel="section"><i class="fa fa-home fa-fw"></i>首页</a></li><li class="menu-item menu-item-tags"><a href="/tags/" rel="section"><i class="fa fa-tags fa-fw"></i>标签</a></li><li class="menu-item menu-item-categories"><a href="/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类</a></li>
      <li class="menu-item menu-item-search">
        <a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索
        </a>
      </li>
  </ul>
</nav>



  <div class="search-pop-overlay">
    <div class="popup search-popup"><div class="search-header">
  <span class="search-icon">
    <i class="fa fa-search"></i>
  </span>
  <div class="search-input-container">
    <input autocomplete="off" autocapitalize="off" maxlength="80"
           placeholder="搜索..." spellcheck="false"
           type="search" class="search-input">
  </div>
  <span class="popup-btn-close" role="button">
    <i class="fa fa-times-circle"></i>
  </span>
</div>
<div class="search-result-container no-result">
  <div class="search-result-icon">
    <i class="fa fa-spinner fa-pulse fa-5x"></i>
  </div>
</div>

    </div>
  </div>

</header>
        
  
  <aside class="sidebar">

    <div class="sidebar-inner sidebar-nav-active sidebar-toc-active">
      <ul class="sidebar-nav">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <div class="sidebar-panel-container">
        <!--noindex-->
        <div class="post-toc-wrap sidebar-panel">
            <div class="post-toc animated"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%88%9D%E5%A7%8B%E5%8C%96"><span class="nav-text">初始化</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E7%94%9F%E6%88%90%E8%B7%AF%E7%94%B1%E8%A1%A8"><span class="nav-text">生成路由表</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#ASM%E4%BB%A3%E7%A0%81%E6%B3%A8%E5%85%A5"><span class="nav-text">ASM代码注入</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E8%B7%AF%E7%94%B1%E6%9F%A5%E6%89%BE"><span class="nav-text">路由查找</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%8F%82%E8%80%83%E6%96%87%E7%AB%A0"><span class="nav-text">参考文章</span></a></li></ol></div>
        </div>
        <!--/noindex-->

        <div class="site-overview-wrap sidebar-panel">
          <div class="site-author animated" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image" alt="Jason"
      src="/images/avatar.png">
  <p class="site-author-name" itemprop="name">Jason</p>
  <div class="site-description" itemprop="description"></div>
</div>
<div class="site-state-wrap animated">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
        <a href="/archives/">
          <span class="site-state-item-count">66</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
          <a href="/categories/">
        <span class="site-state-item-count">13</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
          <a href="/tags/">
        <span class="site-state-item-count">23</span>
        <span class="site-state-item-name">标签</span></a>
      </div>
  </nav>
</div>

        </div>
      </div>
    </div>

    
  </aside>


    </div>

    <div class="main-inner post posts-expand">


  


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="https://rjyblog.gitee.io/posts/23659d3d.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.png">
      <meta itemprop="name" content="Jason">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="任建勇的博客">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="ARouter源码分析 | 任建勇的博客">
      <meta itemprop="description" content="ARouter源码分析">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          ARouter源码分析
        </h1>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2023-09-14 17:23:33" itemprop="dateCreated datePublished" datetime="2023-09-14T17:23:33+08:00">2023-09-14</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar-check"></i>
      </span>
      <span class="post-meta-item-text">更新于</span>
      <time title="修改时间：2023-10-18 09:34:04" itemprop="dateModified" datetime="2023-10-18T09:34:04+08:00">2023-10-18</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/Android/" itemprop="url" rel="index"><span itemprop="name">Android</span></a>
        </span>
    </span>

  
</div>

            <div class="post-description">ARouter源码分析</div>
        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody"><h2 id="初始化"><a href="#初始化" class="headerlink" title="初始化"></a>初始化</h2><?xml version="1.0" encoding="us-ascii" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentStyleType="text/css" height="70px" preserveAspectRatio="none" style="width:247px;height:70px;background:#FFFFFF;" version="1.1" viewBox="0 0 247 70" width="247px" zoomAndPan="magnify"><defs/><g><!--class ARouter--><g id="elem_ARouter"><rect codeLine="1" fill="#F1F1F1" height="56.2656" id="ARouter" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="99" x="7" y="7"/><ellipse cx="22" cy="27.1328" fill="#FF7700" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M25.7813,23.1016 C25.7813,22.6641 25.7656,22.5234 25.6719,22.3672 C25.5313,22.1328 25.25,21.9766 24.9531,21.9766 C24.6094,21.9766 24.4688,22.1172 24.2969,22.5391 C23.7031,22.1641 22.9531,21.9766 22.0781,21.9766 C19.9688,21.9766 18.3906,23.2734 18.3906,24.9922 C18.3906,25.9609 18.9219,26.8672 19.7813,27.3516 C20.3281,27.6641 20.875,27.8359 21.9844,28.0234 C23.1406,28.2266 23.4063,28.2891 23.7656,28.4766 C24.1406,28.6797 24.375,29.0234 24.375,29.3828 C24.375,30.1172 23.3906,30.6641 22.1406,30.6641 C21.0156,30.6641 19.9375,30.1797 19.7656,29.5703 C19.6406,29.1016 19.6406,29.1016 19.5156,28.9922 C19.3594,28.8359 19.1406,28.7422 18.9063,28.7422 C18.625,28.7422 18.375,28.8672 18.2031,29.0859 C18.0938,29.2578 18.0469,29.4453 18.0469,29.8672 L18.0469,30.9922 C18.0469,31.7578 18.3281,32.1172 18.9219,32.1172 C19.1875,32.1172 19.3125,32.0547 19.5938,31.7109 C20.4375,32.1484 21.3281,32.3672 22.25,32.3672 C24.5781,32.3672 26.1406,31.1797 26.1406,29.4141 C26.1406,28.5234 25.8281,27.8359 25.1406,27.2891 C24.6094,26.8672 23.9688,26.6172 22.4844,26.3516 C21.2188,26.1172 21.125,26.0859 20.7969,25.9141 C20.4219,25.7266 20.1563,25.3359 20.1563,24.9766 C20.1563,24.2422 21.0156,23.6797 22.0781,23.6797 C23.1406,23.6797 23.9531,24.1484 24.1094,24.8203 C24.2188,25.3672 24.2188,25.3672 24.3438,25.5078 C24.4844,25.6328 24.7188,25.7422 24.9531,25.7422 C25.2188,25.7422 25.4688,25.6016 25.6406,25.3828 C25.75,25.2109 25.7813,25.0703 25.7813,24.6016 L25.7813,23.1016 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="12" font-style="italic" lengthAdjust="spacing" textLength="71" x="34" y="23.1387">&#171;Singleton&#187;</text><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="59" x="40" y="38.9639">ARouter</text><line style="stroke:#181818;stroke-width:0.5;" x1="8" x2="105" y1="47.2656" y2="47.2656"/><line style="stroke:#181818;stroke-width:0.5;" x1="8" x2="105" y1="55.2656" y2="55.2656"/></g><!--class _ARouter--><g id="elem__ARouter"><rect codeLine="2" fill="#F1F1F1" height="56.2656" id="_ARouter" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="99" x="141" y="7"/><ellipse cx="156" cy="27.1328" fill="#FF7700" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M159.7813,23.1016 C159.7813,22.6641 159.7656,22.5234 159.6719,22.3672 C159.5313,22.1328 159.25,21.9766 158.9531,21.9766 C158.6094,21.9766 158.4688,22.1172 158.2969,22.5391 C157.7031,22.1641 156.9531,21.9766 156.0781,21.9766 C153.9688,21.9766 152.3906,23.2734 152.3906,24.9922 C152.3906,25.9609 152.9219,26.8672 153.7813,27.3516 C154.3281,27.6641 154.875,27.8359 155.9844,28.0234 C157.1406,28.2266 157.4063,28.2891 157.7656,28.4766 C158.1406,28.6797 158.375,29.0234 158.375,29.3828 C158.375,30.1172 157.3906,30.6641 156.1406,30.6641 C155.0156,30.6641 153.9375,30.1797 153.7656,29.5703 C153.6406,29.1016 153.6406,29.1016 153.5156,28.9922 C153.3594,28.8359 153.1406,28.7422 152.9063,28.7422 C152.625,28.7422 152.375,28.8672 152.2031,29.0859 C152.0938,29.2578 152.0469,29.4453 152.0469,29.8672 L152.0469,30.9922 C152.0469,31.7578 152.3281,32.1172 152.9219,32.1172 C153.1875,32.1172 153.3125,32.0547 153.5938,31.7109 C154.4375,32.1484 155.3281,32.3672 156.25,32.3672 C158.5781,32.3672 160.1406,31.1797 160.1406,29.4141 C160.1406,28.5234 159.8281,27.8359 159.1406,27.2891 C158.6094,26.8672 157.9688,26.6172 156.4844,26.3516 C155.2188,26.1172 155.125,26.0859 154.7969,25.9141 C154.4219,25.7266 154.1563,25.3359 154.1563,24.9766 C154.1563,24.2422 155.0156,23.6797 156.0781,23.6797 C157.1406,23.6797 157.9531,24.1484 158.1094,24.8203 C158.2188,25.3672 158.2188,25.3672 158.3438,25.5078 C158.4844,25.6328 158.7188,25.7422 158.9531,25.7422 C159.2188,25.7422 159.4688,25.6016 159.6406,25.3828 C159.75,25.2109 159.7813,25.0703 159.7813,24.6016 L159.7813,23.1016 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="12" font-style="italic" lengthAdjust="spacing" textLength="71" x="168" y="23.1387">&#171;Singleton&#187;</text><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="66" x="170.5" y="38.9639">_ARouter</text><line style="stroke:#181818;stroke-width:0.5;" x1="142" x2="239" y1="47.2656" y2="47.2656"/><line style="stroke:#181818;stroke-width:0.5;" x1="142" x2="239" y1="55.2656" y2="55.2656"/></g><!--link ARouter to _ARouter--><g id="link_ARouter__ARouter"><path codeLine="3" d="M106.2266,35 C117.748,35 123.27,35 134.792,35 " fill="none" id="ARouter-to-_ARouter" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="#181818" points="140.792,35,131.792,31,135.792,35,131.792,39,140.792,35" style="stroke:#181818;stroke-width:1.0;"/></g><!--SRC=[Iyv9B2vMS0pABor9BLAmiL7G2DPHTdCpDpSmq5G8pinBpqajoSzJiBFZIWQhZ2T6AKoDhXrSFG00]--></g></svg>

<p>初始化调用时序</p>
<?xml version="1.0" encoding="us-ascii" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentStyleType="text/css" height="250px" preserveAspectRatio="none" style="width:366px;height:250px;background:#FFFFFF;" version="1.1" viewBox="0 0 366 250" width="366px" zoomAndPan="magnify"><defs/><g><rect fill="#FFFFFF" height="138.5313" style="stroke:#181818;stroke-width:1.0;" width="10" x="46" y="67.4297"/><rect fill="#FFFFFF" height="29.1328" style="stroke:#181818;stroke-width:1.0;" width="10" x="132.5" y="96.5625"/><rect fill="#FFFFFF" height="80.2656" style="stroke:#181818;stroke-width:1.0;" width="10" x="246" y="125.6953"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="50.5" x2="50.5" y1="36.2969" y2="214.9609"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="137.5" x2="137.5" y1="36.2969" y2="214.9609"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="250.5" x2="250.5" y1="36.2969" y2="214.9609"/><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="73" x="14.5" y="5"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="59" x="21.5" y="24.9951">ARouter</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="73" x="14.5" y="213.9609"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="59" x="21.5" y="233.9561">ARouter</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="80" x="97.5" y="5"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="66" x="104.5" y="24.9951">_ARouter</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="80" x="97.5" y="213.9609"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="66" x="104.5" y="233.9561">_ARouter</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="127" x="187.5" y="5"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="113" x="194.5" y="24.9951">LogisticsCenter</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="127" x="187.5" y="213.9609"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="113" x="194.5" y="233.9561">LogisticsCenter</text><rect fill="#FFFFFF" height="138.5313" style="stroke:#181818;stroke-width:1.0;" width="10" x="46" y="67.4297"/><rect fill="#FFFFFF" height="29.1328" style="stroke:#181818;stroke-width:1.0;" width="10" x="132.5" y="96.5625"/><rect fill="#FFFFFF" height="80.2656" style="stroke:#181818;stroke-width:1.0;" width="10" x="246" y="125.6953"/><ellipse cx="7.5" cy="66.6797" fill="none" rx="4" ry="4" style="stroke:#181818;stroke-width:1.5;"/><polygon fill="#181818" points="34,63.4297,44,67.4297,34,71.4297,38,67.4297" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="12" x2="40" y1="67.4297" y2="67.4297"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="19" x="15" y="62.3638">init</text><polygon fill="#181818" points="120.5,92.5625,130.5,96.5625,120.5,100.5625,124.5,96.5625" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="56" x2="126.5" y1="96.5625" y2="96.5625"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="19" x="63" y="91.4966">init</text><polygon fill="#181818" points="234,121.6953,244,125.6953,234,129.6953,238,125.6953" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="137.5" x2="240" y1="125.6953" y2="125.6953"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="19" x="144.5" y="120.6294">init</text><line style="stroke:#181818;stroke-width:1.0;" x1="256" x2="298" y1="154.8281" y2="154.8281"/><line style="stroke:#181818;stroke-width:1.0;" x1="298" x2="298" y1="154.8281" y2="167.8281"/><line style="stroke:#181818;stroke-width:1.0;" x1="257" x2="298" y1="167.8281" y2="167.8281"/><polygon fill="#181818" points="267,163.8281,257,167.8281,267,171.8281,263,167.8281" style="stroke:#181818;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="96" x="263" y="149.7622">loadRouterMap</text><polygon fill="#181818" points="125.5,192.9609,135.5,196.9609,125.5,200.9609,129.5,196.9609" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="56" x2="131.5" y1="196.9609" y2="196.9609"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="50" x="63" y="191.895">afterInit</text><!--SRC=[YyxNjLDm3CelBKajKj3MjbB8pCiiuO890ENYCIJZaMHzyjCpYqioaukTK_F0GhfmPHXIcAgj57Bo4rCWflac5c2praeXCGr8UG9D1000]--></g></svg>

<h2 id="生成路由表"><a href="#生成路由表" class="headerlink" title="生成路由表"></a>生成路由表</h2><p>ARouter是通过在编译阶段使用<a target="_blank" rel="noopener external nofollow noreferrer" href="https://kotlinlang.org/docs/kapt.html">kapt</a>解析Route注解，再通过<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/square/javapoet">javapoet</a>来生成路由表相关代码。注解处理器在<code>arouter-compiler/src/main/java/com/alibaba/android/arouter/compiler/processor/RouteProcessor.java</code>。</p>
<p>比如<code>module-kotlin</code>模块有三个activity，路由分别是：</p>
<ul>
<li>/one/first</li>
<li>/one/second</li>
<li>/two/test</li>
</ul>
<p>生成的路由表如下：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//生成目录位于module-kotlin/build/generated/source/kapt/debug/com/alibaba/android/arouter/routes</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ARouter$$Root$$modulekotlin</span> <span class="keyword">implements</span> <span class="title class_">IRouteRoot</span> &#123;</span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">loadInto</span><span class="params">(Map&lt;String, Class&lt;? extends IRouteGroup&gt;&gt; routes)</span> &#123;</span><br><span class="line">    routes.put(<span class="string">&quot;one&quot;</span>, ARouter$$Group$$one.class);</span><br><span class="line">    routes.put(<span class="string">&quot;two&quot;</span>, ARouter$$Group$$two.class);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ARouter$$Group$$one</span> <span class="keyword">implements</span> <span class="title class_">IRouteGroup</span> &#123;</span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">loadInto</span><span class="params">(Map&lt;String, RouteMeta&gt; atlas)</span> &#123;</span><br><span class="line">    atlas.put(<span class="string">&quot;/one/first&quot;</span>, RouteMeta.build(RouteType.ACTIVITY, FistActivity.class, <span class="string">&quot;/one/first&quot;</span>, <span class="string">&quot;one&quot;</span>, <span class="literal">null</span>, -<span class="number">1</span>, -<span class="number">2147483648</span>));</span><br><span class="line">    atlas.put(<span class="string">&quot;/one/second&quot;</span>, RouteMeta.build(RouteType.ACTIVITY, SecondActivity.class, <span class="string">&quot;/one/second&quot;</span>, <span class="string">&quot;two&quot;</span>, <span class="literal">null</span>, -<span class="number">1</span>, -<span class="number">2147483648</span>));</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ARouter$$Group$$two</span> <span class="keyword">implements</span> <span class="title class_">IRouteGroup</span> &#123;</span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">loadInto</span><span class="params">(Map&lt;String, RouteMeta&gt; atlas)</span> &#123;</span><br><span class="line">    atlas.put(<span class="string">&quot;/two/test&quot;</span>, RouteMeta.build(RouteType.ACTIVITY, TestActivity.class, <span class="string">&quot;/two/test&quot;</span>, <span class="string">&quot;two&quot;</span>, <span class="literal">null</span>, -<span class="number">1</span>, -<span class="number">2147483648</span>));</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>编译自动生成的代码包含一个Root（<code>IRouteRoot</code>）和两个Group（<code>IRouteGroup</code>）。Root是module模块下路由表入口类，使用模块名称命名生成类<code>ARouter$$Root$$modulekotlin</code>。Group是二级路由路径的第一级<small>（/one/first中的one）</small>，本例中分别是one和two，分别对应类<code>ARouter$$Group$$one</code>和<code>ARouter$$Group$$two</code>，每个Group类下面才是真正的路由。</p>
<p>从代码中可以看出来<code>ARouter$$Root$$modulekotlin</code>会把两个Group对应的class添加到group列表中。那么，<code>com.alibaba.android.arouter.routes.ARouter$$Root$$modulekotlin#loadInto</code>方法什么时候被执行呢？代码中找不到调用的地方，实际上是在<code>LogisticsCenter#loadRouterMap</code>方法中调用，这个方法会在编译期间动态插入代码。见<a href="#asm%E4%BB%A3%E7%A0%81%E6%B3%A8%E5%85%A5">下一节</a>介绍。</p>
<p>备注：<a target="_blank" rel="noopener external nofollow noreferrer" href="https://kotlinlang.org/docs/kapt.html">kapt</a>相当于java apt，kapt同时支持kotlin和java代码的注解。kapt生成的代码在<code>module-kotlin/build/generated/source/kapt</code>目录下，apt生成的代码在<code>module-java/build/generated/ap_generated_sources</code>目录下。</p>
<h2 id="ASM代码注入"><a href="#ASM代码注入" class="headerlink" title="ASM代码注入"></a>ASM代码注入</h2><p>在ARouter初始化流程中会调用<code>com.alibaba.android.arouter.core.LogisticsCenter#loadRouterMap</code>方法，该方法负责填充Group表。原始代码如下：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//LogisticsCenter.java</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">loadRouterMap</span><span class="params">()</span> &#123;</span><br><span class="line">        registerByPlugin = <span class="literal">false</span>;</span><br><span class="line">        <span class="comment">// auto generate register code by gradle plugin: arouter-auto-register</span></span><br><span class="line">        <span class="comment">// looks like below:</span></span><br><span class="line">        <span class="comment">// registerRouteRoot(new ARouter..Root..modulejava());</span></span><br><span class="line">        <span class="comment">// registerRouteRoot(new ARouter..Root..modulekotlin());</span></span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<p>方法中没有任何注册逻辑。实际上这个方法会在编译期间通过<a target="_blank" rel="noopener external nofollow noreferrer" href="https://asm.ow2.io/asm4-guide.pdf">ASM</a>来修改方法的实现。ASM注入代码后：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//LogisticsCenter.class</span></span><br><span class="line">  <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">loadRouterMap</span><span class="params">()</span> &#123;</span><br><span class="line">    registerByPlugin = <span class="literal">false</span>;</span><br><span class="line">    register(<span class="string">&quot;com.alibaba.android.arouter.routes.ARouter$$Root$$modulejava&quot;</span>);</span><br><span class="line">    register(<span class="string">&quot;com.alibaba.android.arouter.routes.ARouter$$Root$$modulekotlin&quot;</span>);</span><br><span class="line">    register(<span class="string">&quot;com.alibaba.android.arouter.routes.ARouter$$Root$$arouterapi&quot;</span>);</span><br><span class="line">    register(<span class="string">&quot;com.alibaba.android.arouter.routes.ARouter$$Interceptors$$modulejava&quot;</span>);</span><br><span class="line">    register(<span class="string">&quot;com.alibaba.android.arouter.routes.ARouter$$Providers$$modulejava&quot;</span>);</span><br><span class="line">    register(<span class="string">&quot;com.alibaba.android.arouter.routes.ARouter$$Providers$$modulekotlin&quot;</span>);</span><br><span class="line">    register(<span class="string">&quot;com.alibaba.android.arouter.routes.ARouter$$Providers$$arouterapi&quot;</span>);</span><br><span class="line">  &#125;</span><br></pre></td></tr></table></figure>

<p>代码注入在arouter-gradle-plugin插件中实现，代码对应在<code>arouter-gradle-plugin/src/main/groovy/com/alibaba/android/arouter/register/launch/PluginLaunch.groovy</code>文件中，插件会注册一个RegisterTransform，这个Transform会在<code>*.class</code>转换成dex文件之前运行。</p>
<p>注入的代码是调用register函数，定义如下：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//LogisticsCenter.java</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">register</span><span class="params">(String className)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (!TextUtils.isEmpty(className)) &#123;</span><br><span class="line">            <span class="keyword">try</span> &#123;</span><br><span class="line">                Class&lt;?&gt; clazz = Class.forName(className);</span><br><span class="line">                <span class="comment">//1.通过反射调用类构造方法</span></span><br><span class="line">                <span class="type">Object</span> <span class="variable">obj</span> <span class="operator">=</span> clazz.getConstructor().newInstance(); </span><br><span class="line">                <span class="keyword">if</span> (obj <span class="keyword">instanceof</span> IRouteRoot) &#123;</span><br><span class="line">                    registerRouteRoot((IRouteRoot) obj);</span><br><span class="line">                &#125; <span class="keyword">else</span> <span class="keyword">if</span> (obj <span class="keyword">instanceof</span> IProviderGroup) &#123;</span><br><span class="line">                    registerProvider((IProviderGroup) obj);</span><br><span class="line">                &#125; <span class="keyword">else</span> <span class="keyword">if</span> (obj <span class="keyword">instanceof</span> IInterceptorGroup) &#123;</span><br><span class="line">                    registerInterceptor((IInterceptorGroup) obj);</span><br><span class="line">                &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                    logger.info(TAG, <span class="string">&quot;register failed, class name: &quot;</span> + className</span><br><span class="line">                            + <span class="string">&quot; should implements one of IRouteRoot/IProviderGroup/IInterceptorGroup.&quot;</span>);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">                logger.error(TAG,<span class="string">&quot;register class error:&quot;</span> + className, e);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">registerRouteRoot</span><span class="params">(IRouteRoot routeRoot)</span> &#123;</span><br><span class="line">        markRegisteredByPlugin();</span><br><span class="line">        <span class="keyword">if</span> (routeRoot != <span class="literal">null</span>) &#123;</span><br><span class="line">            <span class="comment">//2.调用loadInto方法</span></span><br><span class="line">            routeRoot.loadInto(Warehouse.groupsIndex);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<p>从上述代码可以看到先通过反射方式创建<code>com.alibaba.android.arouter.routes.ARouter$$Root$$modulekotlin</code>类的实例对象，然后调用它的loadInto方法。最终效果是group被注册到<code>Warehouse.groupsIndex</code>这个map中，相当于下面这段代码：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Warehouse.groupsIndex.put(<span class="string">&quot;kotlin&quot;</span>, ARouter$$Group$$kotlin.class)</span><br></pre></td></tr></table></figure>

<p><strong>备注：</strong> 如果期望编译时打印代码注入相关的日志，可以使用下面命令行进行编译</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">./gradlew clean &amp;&amp; ./gradlew -i :app:assembleDebug | tee build_log.txt</span><br></pre></td></tr></table></figure>

<h2 id="路由查找"><a href="#路由查找" class="headerlink" title="路由查找"></a>路由查找</h2><p>ARouter初始化完成之后，如果没有发生路由跳转，路由表就还是空的，但group表是有数据。当发生路由跳转时，会首先查找路由表，由于是首次跳转，路由表中找不到路由，就会在group表中查找路由对应的group类，把这个group下面的所有路由注册到路由表，然后再进行跳转。当下次再跳转时路由表中就存在对应的路由了。</p>
<?xml version="1.0" encoding="us-ascii" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentStyleType="text/css" height="548px" preserveAspectRatio="none" style="width:833px;height:548px;background:#FFFFFF;" version="1.1" viewBox="0 0 833 548" width="833px" zoomAndPan="magnify"><defs/><g><ellipse cx="224" cy="20" fill="#222222" rx="10" ry="10" style="stroke:#222222;stroke-width:1.0;"/><rect fill="#F1F1F1" height="33.9688" rx="12.5" ry="12.5" style="stroke:#181818;stroke-width:0.5;" width="139" x="154.5" y="50"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="119" x="164.5" y="71.1387">&#36339;&#36716;&#39029;&#38754;navigation()</text><path d="M366,181.6987 L366,312.7612 L821,312.7612 L821,191.6987 L811,181.6987 L366,181.6987 " fill="#FEFFDD" style="stroke:#181818;stroke-width:0.5;"/><path d="M811,181.6987 L811,191.6987 L821,191.6987 L811,181.6987 " fill="#FEFFDD" style="stroke:#181818;stroke-width:0.5;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="122" x="372" y="198.7656">class Warehouse {</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="88" x="388" y="213.8984">// &#12304;group&#34920;&#12305;</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="414" x="388" y="229.0313">static Map&lt;String, Class&lt;? extends IRouteGroup&gt;&gt; groupsIndex</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="138" x="628" y="244.1641">= new HashMap&lt;&gt;();</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="77" x="388" y="259.2969">// &#12304;&#36335;&#30001;&#34920;&#12305;</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="386" x="388" y="274.4297">static Map&lt;String, RouteMeta&gt; routes = new HashMap&lt;&gt;();</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="24" x="388" y="289.5625">......</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="9" x="372" y="304.6953">}</text><rect fill="#F1F1F1" height="33.9688" rx="12.5" ry="12.5" style="stroke:#181818;stroke-width:0.5;" width="164" x="142" y="159.6792"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="144" x="152" y="180.8179">&#22312;group&#34920;&#20013;&#26597;&#25214;group&#31867;</text><polygon fill="#F1F1F1" points="197,228.6479,251,228.6479,263,240.6479,251,252.6479,197,252.6479,185,240.6479,197,228.6479" style="stroke:#181818;stroke-width:0.5;"/><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="54" x="197" y="244.4561">&#23384;&#22312;group</text><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="21" x="164" y="238.0537">yes</text><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="14" x="263" y="238.0537">no</text><rect fill="#F1F1F1" height="33.9688" rx="12.5" ry="12.5" style="stroke:#181818;stroke-width:0.5;" width="151" x="68.5" y="262.6479"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="131" x="78.5" y="283.7866">&#21453;&#23556;&#21021;&#22987;&#21270;group class</text><rect fill="#F1F1F1" height="33.9688" rx="12.5" ry="12.5" style="stroke:#181818;stroke-width:0.5;" width="212" x="38" y="331.6167"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="192" x="48" y="352.7554">group&#19979;&#30340;&#25152;&#26377;&#36335;&#30001;&#28155;&#21152;&#21040;&#36335;&#30001;&#34920;&#20013;</text><rect fill="#F1F1F1" height="33.9688" rx="12.5" ry="12.5" style="stroke:#181818;stroke-width:0.5;" width="68" x="270" y="262.6479"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="48" x="280" y="283.7866">&#25243;&#20986;&#24322;&#24120;</text><ellipse cx="304" cy="342.6167" fill="none" rx="11" ry="11" style="stroke:#222222;stroke-width:1.0;"/><ellipse cx="304" cy="342.6167" fill="#222222" rx="6" ry="6" style="stroke:#222222;stroke-width:1.0;"/><polygon fill="#F1F1F1" points="174.5,103.9688,273.5,103.9688,285.5,115.9688,273.5,127.9688,174.5,127.9688,162.5,115.9688,174.5,103.9688" style="stroke:#181818;stroke-width:0.5;"/><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="33" x="228" y="138.1792">&#19981;&#23384;&#22312;</text><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="99" x="174.5" y="119.7769">&#36335;&#30001;&#34920;&#20013;&#23384;&#22312;&#36335;&#30001;&#65311;</text><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="22" x="140.5" y="113.3745">&#23384;&#22312;</text><rect fill="#F1F1F1" height="33.9688" rx="12.5" ry="12.5" style="stroke:#181818;stroke-width:0.5;" width="144" x="152" y="407.5854"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="124" x="162" y="428.7241">&#36335;&#30001;&#20449;&#24687;&#22635;&#20805;Postcard</text><rect fill="#F1F1F1" height="33.9688" rx="12.5" ry="12.5" style="stroke:#181818;stroke-width:0.5;" width="128" x="160" y="461.5542"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="108" x="170" y="482.6929">&#25191;&#34892;&#25318;&#25130;&#21644;&#36339;&#36716;&#36923;&#36753;</text><ellipse cx="224" cy="526.5229" fill="none" rx="11" ry="11" style="stroke:#222222;stroke-width:1.0;"/><ellipse cx="224" cy="526.5229" fill="#222222" rx="6" ry="6" style="stroke:#222222;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="224" x2="224" y1="30" y2="50"/><polygon fill="#181818" points="220,40,224,50,228,40,224,44" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="144" x2="144" y1="296.6167" y2="331.6167"/><polygon fill="#181818" points="140,321.6167,144,331.6167,148,321.6167,144,325.6167" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="304" x2="304" y1="296.6167" y2="331.6167"/><polygon fill="#181818" points="300,321.6167,304,331.6167,308,321.6167,304,325.6167" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="185" x2="144" y1="240.6479" y2="240.6479"/><line style="stroke:#181818;stroke-width:1.0;" x1="144" x2="144" y1="240.6479" y2="262.6479"/><polygon fill="#181818" points="140,252.6479,144,262.6479,148,252.6479,144,256.6479" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="263" x2="304" y1="240.6479" y2="240.6479"/><line style="stroke:#181818;stroke-width:1.0;" x1="304" x2="304" y1="240.6479" y2="262.6479"/><polygon fill="#181818" points="300,252.6479,304,262.6479,308,252.6479,304,256.6479" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="144" x2="144" y1="365.5854" y2="370.5854"/><line style="stroke:#181818;stroke-width:1.0;" x1="144" x2="352" y1="370.5854" y2="370.5854"/><polygon fill="#181818" points="348,251.23,352,241.23,356,251.23,352,247.23" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="352" x2="352" y1="115.9688" y2="370.5854"/><line style="stroke:#181818;stroke-width:1.0;" x1="352" x2="285.5" y1="115.9688" y2="115.9688"/><polygon fill="#181818" points="295.5,111.9688,285.5,115.9688,295.5,119.9688,291.5,115.9688" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="224" x2="224" y1="193.6479" y2="228.6479"/><polygon fill="#181818" points="220,218.6479,224,228.6479,228,218.6479,224,222.6479" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="224" x2="224" y1="127.9688" y2="159.6792"/><polygon fill="#181818" points="220,149.6792,224,159.6792,228,149.6792,224,153.6792" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="162.5" x2="24" y1="115.9688" y2="115.9688"/><polygon fill="#181818" points="20,243.23,24,253.23,28,243.23,24,247.23" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="24" x2="24" y1="115.9688" y2="387.5854"/><line style="stroke:#181818;stroke-width:1.0;" x1="24" x2="224" y1="387.5854" y2="387.5854"/><line style="stroke:#181818;stroke-width:1.0;" x1="224" x2="224" y1="387.5854" y2="407.5854"/><polygon fill="#181818" points="220,397.5854,224,407.5854,228,397.5854,224,401.5854" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="224" x2="224" y1="83.9688" y2="103.9688"/><polygon fill="#181818" points="220,93.9688,224,103.9688,228,93.9688,224,97.9688" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="224" x2="224" y1="441.5542" y2="461.5542"/><polygon fill="#181818" points="220,451.5542,224,461.5542,228,451.5542,224,455.5542" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="224" x2="224" y1="495.5229" y2="515.5229"/><polygon fill="#181818" points="220,505.5229,224,515.5229,228,505.5229,224,509.5229" style="stroke:#181818;stroke-width:1.0;"/><!--SRC=[fP9DIoCn6CVlyocUump8Uf_Mxi63UX143tiERTePA4cPfDf55hgBOcihwh8ieYrr15_m1IqY7RPTzyFOfEF9hs2IqU9UTWy-Xv3ya-UNvurn573BZNktyU_Bn_3kiNr4qB9VGDodn7PIrehd5x4Tzwv7FxfnU3QChiJLdcYT9ShJeEE0p-nXj9N8ZWMGBrBbJWf0ACSG-0MFAnKWMqICmISKO8-M6OPLesgRd8I7wauXeEMI-kEXkZk-OLoXiZ2FIkab7YZe14nhJFeZu0h79CTWRf6MEPxHpfaC60YR8pbSWJ7bFJO51A_0B6AU3YAZQ_9tsEFQ_2Tk4-OyvYW3WTwoVw4_63F7BsfLYPfgggshglnQATKDsJcMzNiZZBfz3V3pO2VDCAe3tCF4_eoPOt2ksDuIDskYrXQd3T7yQHublKc-TuqoZ1gZ_JLPhyfMFSbGzlfYyr3KRjuEWtR1HTLCcz0Nljmy41k_nE2RYAA4o3Wj9KduUKkjPgPUWtJqz6dWy4yelrwBy4AihozGnhCeoAKiLzPFux0f6oUoTYw-DrycjTgFxtTJbYO_0m00]--></g></svg>

<p>我们通过跳转路由名为<code>/kotlin/test</code>的activity来介绍一下源码实现。使用下面方法打开activity：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ARouter.getInstance().build(<span class="string">&quot;/kotlin/test&quot;</span>).navigation();</span><br></pre></td></tr></table></figure>

<p>navigation有好几个重载方法，最终都会走到下面的方法：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">final</span> <span class="keyword">class</span> <span class="title class_">ARouter</span> &#123;</span><br><span class="line">    ......</span><br><span class="line">    <span class="keyword">public</span> Object <span class="title function_">navigation</span><span class="params">(Context mContext, Postcard postcard, <span class="type">int</span> requestCode, NavigationCallback callback)</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> _ARouter.getInstance().navigation(mContext, postcard, requestCode, callback);</span><br><span class="line">    &#125;</span><br><span class="line">    ......</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//_ARouter.java</span></span><br><span class="line">    <span class="keyword">protected</span> Object <span class="title function_">navigation</span><span class="params">(<span class="keyword">final</span> Context context, <span class="keyword">final</span> Postcard postcard, <span class="keyword">final</span> <span class="type">int</span> requestCode, <span class="keyword">final</span> NavigationCallback callback)</span> &#123;</span><br><span class="line">        ......</span><br><span class="line">        <span class="comment">// Set context to postcard.</span></span><br><span class="line">        postcard.setContext(<span class="literal">null</span> == context ? mContext : context);</span><br><span class="line"></span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            LogisticsCenter.completion(postcard); <span class="comment">//执行上面流程图的逻辑，代码就不贴了</span></span><br><span class="line">        &#125; <span class="keyword">catch</span> (NoRouteFoundException ex) &#123;</span><br><span class="line">            ......</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (<span class="literal">null</span> != callback) &#123;</span><br><span class="line">            callback.onFound(postcard);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (!postcard.isGreenChannel()) &#123;   <span class="comment">// It must be run in async thread, maybe interceptor cost too mush time made ANR.</span></span><br><span class="line">            interceptorService.doInterceptions(postcard, <span class="keyword">new</span> <span class="title class_">InterceptorCallback</span>() &#123;</span><br><span class="line">                <span class="meta">@Override</span></span><br><span class="line">                <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">onContinue</span><span class="params">(Postcard postcard)</span> &#123;</span><br><span class="line">                    _navigation(postcard, requestCode, callback);</span><br><span class="line">                &#125;</span><br><span class="line"></span><br><span class="line">                <span class="meta">@Override</span></span><br><span class="line">                <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">onInterrupt</span><span class="params">(Throwable exception)</span> &#123;</span><br><span class="line">                    <span class="keyword">if</span> (<span class="literal">null</span> != callback) &#123;</span><br><span class="line">                        callback.onInterrupt(postcard);</span><br><span class="line">                    &#125;</span><br><span class="line"></span><br><span class="line">                    logger.info(Consts.TAG, <span class="string">&quot;Navigation failed, termination by interceptor : &quot;</span> + exception.getMessage());</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;);</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> _navigation(postcard, requestCode, callback);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> <span class="literal">null</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> Object <span class="title function_">_navigation</span><span class="params">(<span class="keyword">final</span> Postcard postcard, <span class="keyword">final</span> <span class="type">int</span> requestCode, <span class="keyword">final</span> NavigationCallback callback)</span> &#123;</span><br><span class="line">        <span class="keyword">final</span> <span class="type">Context</span> <span class="variable">currentContext</span> <span class="operator">=</span> postcard.getContext();</span><br><span class="line"></span><br><span class="line">        <span class="keyword">switch</span> (postcard.getType()) &#123;</span><br><span class="line">            <span class="keyword">case</span> ACTIVITY:</span><br><span class="line">                <span class="comment">// Build intent</span></span><br><span class="line">                <span class="keyword">final</span> <span class="type">Intent</span> <span class="variable">intent</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Intent</span>(currentContext, postcard.getDestination());</span><br><span class="line">                intent.putExtras(postcard.getExtras());</span><br><span class="line"></span><br><span class="line">                <span class="comment">// Set flags.</span></span><br><span class="line">                <span class="type">int</span> <span class="variable">flags</span> <span class="operator">=</span> postcard.getFlags();</span><br><span class="line">                <span class="keyword">if</span> (<span class="number">0</span> != flags) &#123;</span><br><span class="line">                    intent.setFlags(flags);</span><br><span class="line">                &#125;</span><br><span class="line"></span><br><span class="line">                <span class="comment">// Non activity, need FLAG_ACTIVITY_NEW_TASK</span></span><br><span class="line">                <span class="keyword">if</span> (!(currentContext <span class="keyword">instanceof</span> Activity)) &#123;</span><br><span class="line">                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);</span><br><span class="line">                &#125;</span><br><span class="line"></span><br><span class="line">                <span class="comment">// Set Actions</span></span><br><span class="line">                <span class="type">String</span> <span class="variable">action</span> <span class="operator">=</span> postcard.getAction();</span><br><span class="line">                <span class="keyword">if</span> (!TextUtils.isEmpty(action)) &#123;</span><br><span class="line">                    intent.setAction(action);</span><br><span class="line">                &#125;</span><br><span class="line"></span><br><span class="line">                <span class="comment">// Navigation in main looper.</span></span><br><span class="line">                runInMainThread(<span class="keyword">new</span> <span class="title class_">Runnable</span>() &#123;</span><br><span class="line">                    <span class="meta">@Override</span></span><br><span class="line">                    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">run</span><span class="params">()</span> &#123;</span><br><span class="line">                        startActivity(requestCode, currentContext, intent, postcard, callback);</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;);</span><br><span class="line"></span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            ......</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> <span class="literal">null</span>;</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<p>找到路由<code>/kotlin/test</code>对应的group类后（本例中对应<code>ARouter$$Group$$kotlin.class</code>），就会利用反射调用group类的初始化，然后调用其loadInto方法将路由注册到路由表<code>Warehouse#routes</code>中，源码如下：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">LogisticsCenter</span> &#123;</span><br><span class="line">    ......</span><br><span class="line">    <span class="comment">//本例中groupName=&quot;kotlin&quot;，group=null</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">synchronized</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">addRouteGroupDynamic</span><span class="params">(String groupName, IRouteGroup group)</span> <span class="keyword">throws</span> NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException &#123;</span><br><span class="line">        <span class="keyword">if</span> (Warehouse.groupsIndex.containsKey(groupName))&#123;</span><br><span class="line">            <span class="comment">//利用反射调用group类的构造方法，然后调用loadInto方法</span></span><br><span class="line">            Warehouse.groupsIndex.get(groupName).getConstructor().newInstance().loadInto(Warehouse.routes);</span><br><span class="line">            <span class="comment">//将对应的group类在group表中删除，因为路由注册到路由表后，group类就可以回收了</span></span><br><span class="line">            Warehouse.groupsIndex.remove(groupName);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// cover old group.</span></span><br><span class="line">        <span class="keyword">if</span> (<span class="literal">null</span> != group) &#123;</span><br><span class="line">            group.loadInto(Warehouse.routes);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="参考文章"><a href="#参考文章" class="headerlink" title="参考文章"></a>参考文章</h2><p><a target="_blank" rel="noopener external nofollow noreferrer" href="https://juejin.cn/post/6914485867029463054">一文学会Android Gradle Transform基础使用</a><br><a target="_blank" rel="noopener external nofollow noreferrer" href="https://cloud.tencent.com/developer/article/1920027">Android APK编译流程</a><br><a target="_blank" rel="noopener external nofollow noreferrer" href="https://zhuanlan.zhihu.com/p/263806589">AOP 利器 ——ASM 基础入门</a></p>

    </div>

    
    
    

    <footer class="post-footer">
          <div class="post-tags">
              <a href="/tags/Android/" rel="tag"># Android</a>
              <a href="/tags/ARouter/" rel="tag"># ARouter</a>
          </div>

        

          <div class="post-nav">
            <div class="post-nav-item">
                <a href="/posts/faedbb97.html" rel="prev" title="LeakCanary源码详解">
                  <i class="fa fa-angle-left"></i> LeakCanary源码详解
                </a>
            </div>
            <div class="post-nav-item">
                <a href="/posts/ca4438af.html" rel="next" title="HashMap源码分析">
                  HashMap源码分析 <i class="fa fa-angle-right"></i>
                </a>
            </div>
          </div>
    </footer>
  </article>
</div>






</div>
  </main>

  <footer class="footer">
    <div class="footer-inner">

  <div class="copyright">
    &copy; 
    <span itemprop="copyrightYear">2024</span>
    <span class="with-love">
      <i class="fa fa-heart"></i>
    </span>
    <span class="author" itemprop="copyrightHolder">Jason</span>
  </div>
  <div class="powered-by">由 <a href="https://hexo.io/" rel="noopener external nofollow noreferrer" target="_blank">Hexo</a> & <a href="https://theme-next.js.org/pisces/" rel="noopener external nofollow noreferrer" target="_blank">NexT.Pisces</a> 强力驱动
  </div>

    </div>
  </footer>

  
  <div class="back-to-top" role="button" aria-label="返回顶部">
    <i class="fa fa-arrow-up fa-lg"></i>
    <span>0%</span>
  </div>

<noscript>
  <div class="noscript-warning">Theme NexT works best with JavaScript enabled</div>
</noscript>


  
  <script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js" integrity="sha256-XL2inqUJaslATFnHdJOi9GfQ60on8Wx1C2H8DYiN1xY=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/next-theme-pjax/0.6.0/pjax.min.js" integrity="sha256-vxLn1tSKWD4dqbMRyv940UYw4sXgMtYcK6reefzZrao=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/fancyapps-ui/5.0.24/fancybox/fancybox.umd.js" integrity="sha256-oyhjPiYRWGXaAt+ny/mTMWOnN1GBoZDUQnzzgC7FRI4=" crossorigin="anonymous"></script>
<script src="/js/comments.js"></script><script src="/js/utils.js"></script><script src="/js/motion.js"></script><script src="/js/next-boot.js"></script><script src="/js/pjax.js"></script>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/hexo-generator-searchdb/1.4.1/search.js" integrity="sha256-1kfA5uHPf65M5cphT2dvymhkuyHPQp5A53EGZOnOLmc=" crossorigin="anonymous"></script>
<script src="/js/third-party/search/local-search.js"></script>


  <script class="next-config" data-name="mermaid" type="application/json">{"enable":true,"theme":{"light":"default","dark":"dark"},"js":{"url":"https://cdnjs.cloudflare.com/ajax/libs/mermaid/10.5.0/mermaid.min.js","integrity":"sha256-K7oJiQlDulzl24ZUFOywuYme1JqBBvQzK6m8qHjt9Gk="}}</script>
  <script type="module" src="/js/zenuml-definition-074a43fa.js"></script>
  <script type="module" src="/js/mermaid-zenuml.esm.min.mjs"></script>
  <script src="/js/third-party/tags/mermaid.js"></script>


  <script src="/js/third-party/fancybox.js"></script>



  




  

  <script class="next-config" data-name="enableMath" type="application/json">true</script><script class="next-config" data-name="mathjax" type="application/json">{"enable":true,"tags":"none","js":{"url":"https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.2.2/es5/tex-mml-chtml.js","integrity":"sha256-MASABpB4tYktI2Oitl4t+78w/lyA+D7b/s9GEP0JOGI="}}</script>
<script src="/js/third-party/math/mathjax.js"></script>



</body>
</html>
